package com.hx.jvm.classloader.hotdeploy;

import com.hx.jvm.proxy.jdk.IHello;

import java.io.File;

/**
 * @author Minghua Chen
 * @since on 2020/8/17 12:44
 */
public class Client {
    private static final String CLASS_NAME = "com.hx.jvm.classloader.hotdeploy.HelloImpl";

    // class文件真实所在位置
    private static final String FILE_NAME = "D:/me/gitcode/testloader/" + CLASS_NAME.replaceAll("\\.", "/") + ".class";
    private static volatile IHello hello;

    // 获取hello
    public static IHello getHello() {
        if (hello != null) {
            return hello;
        }
        synchronized (Client.class) {
            if (hello == null) {
                hello = createHello();
            }
            return hello;
        }
    }

    // 创建hello
    private static IHello createHello() {
        try {
            // 通过自定义类加载器加载
            MyClassLoader loader = new MyClassLoader();
            Class<?> clazz = loader.findClass(CLASS_NAME);
            if (clazz != null) {
                return (IHello) clazz.newInstance();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    // 启动的客户端
    public static void client() {
        Thread thread = new Thread(() -> {
            try {
                while (true) {
                    IHello hello = getHello();
                    hello.sayHello();
                    Thread.sleep(1000);
                }
            } catch (Exception ignored) {
            }
        });
        thread.start();
    }
    // 监控线程

    public static void monitor() {
        Thread thread = new Thread() {
            private long lastModified = new File(FILE_NAME).lastModified();

            @Override
            public void run() {
                try {
                    while (true) {
                        Thread.sleep(100);
                        long now = new File(FILE_NAME).lastModified();
                        if (lastModified != now) {
                            lastModified = now;
                            reloadHello();
                        }
                    }
                } catch (InterruptedException e) {
                }
            }
        };
        thread.start();
    }

    private static void reloadHello() {
        hello = createHello();
    }

    public static void main(String[] args) {
        monitor();
        client();
    }
}
